package com.ht.demo.service.manager.system.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ht.demo.common.appexception.AppErrorCodeEnum;
import com.ht.demo.common.appexception.AppException;
import com.ht.demo.common.constans.SystemConstant;
import com.ht.demo.common.page.PageBO;
import com.ht.demo.common.pojo.bo.system.FilterUrlConfigBO;
import com.ht.demo.common.pojo.qto.system.FilterUrlConfigQTO;
import com.ht.demo.dao.domain.system.FilterUrlConfigDO;
import com.ht.demo.service.convert.system.FilterUrlConfigBeanUtil;
import com.ht.demo.service.manager.system.FilterUrlConfigManager;
import com.ht.demo.service.mapper.system.FilterUrlConfigMapper;
import com.ht.demo.service.redis.RedisKeyUtil;
import com.ht.demo.service.redis.RedisUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author hdengxian
 * @Date 2023/3/28 10:23
 */
@Component
public class FilterUrlConfigManagerImpl implements FilterUrlConfigManager {
    Logger logger = LoggerFactory.getLogger(FilterUrlConfigManagerImpl.class);
    @Resource
    private  FilterUrlConfigMapper filterUrlConfigMapper;
    @Resource
    private  RedisUtil redisUtil;

    /**
     * 系统启动时初始化一次
     * 所以但发生修改或新增时需要再次执行一次
     */
    @PostConstruct
    public void init(){
        List<FilterUrlConfigBO> boList = FilterUrlConfigBeanUtil.doList2BOList(filterUrlConfigMapper.findAll());
        for (FilterUrlConfigBO bo : boList) {
            redisUtil.set(RedisKeyUtil.getFilterUrlKey(bo.getFilterType(), bo.getRequestUri()), bo.getRequestName());
        }
        logger.info("- FilterUrlConfigManagerImpl.init - 初始化需要过滤的地址保存到redis成功");
    }


    @Override
    public Boolean insertFilterUrl(FilterUrlConfigBO configBO) throws AppException {
        FilterUrlConfigBeanUtil.addCheckParam(configBO);
        LambdaQueryWrapper<FilterUrlConfigDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FilterUrlConfigDO::getFilterType, configBO.getFilterType());
        wrapper.eq(FilterUrlConfigDO::getRequestUri, configBO.getRequestUri());
        int count = filterUrlConfigMapper.count(wrapper);
        if (count > 0) {
            throw new AppException("该地址已添加，请勿重复添加");
        }
        configBO.setCreateTime(new Date());
        configBO.setUpdateTime(new Date());
        configBO.setDeleted(SystemConstant.STR_0);
        FilterUrlConfigDO configDO = FilterUrlConfigBeanUtil.filterUrlConfigBOToDO(configBO);
        filterUrlConfigMapper.save(configDO);

        init();

        return true;
    }

    @Override
    public Boolean updateFilterUrl(FilterUrlConfigBO configBO) throws AppException {
        if (configBO == null || configBO.getFilterUrlConfigId() == null) {
            throw new AppException(AppErrorCodeEnum.PARAMETER_ERROR);
        }
        FilterUrlConfigDO old = filterUrlConfigMapper.getById(configBO.getFilterUrlConfigId());
        if (old == null) {
            throw new AppException(AppErrorCodeEnum.UPDATE_DATE_NOT_EXISTS);
        }
        Boolean flag = StringUtils.isNotBlank(configBO.getFilterType()) && !old.getFilterType().equals(configBO.getFilterType());
        Boolean flag1 = StringUtils.isNotBlank(configBO.getRequestUri()) && !old.getRequestUri().equals(configBO.getRequestUri());

        LambdaQueryWrapper<FilterUrlConfigDO> wrapper = new LambdaQueryWrapper<>();
        int count = 0;
        if (flag && flag1) {
            //修改了type和url
            wrapper.eq(FilterUrlConfigDO::getFilterType, configBO.getFilterType());
            wrapper.eq(FilterUrlConfigDO::getRequestUri, configBO.getRequestUri());
            count = filterUrlConfigMapper.count(wrapper);
        } else if (flag && !flag1) {
            //只修改了type
            wrapper.eq(FilterUrlConfigDO::getFilterType, configBO.getFilterType());
            wrapper.eq(FilterUrlConfigDO::getRequestUri, old.getRequestUri());
            count = filterUrlConfigMapper.count(wrapper);
        } else if (flag1 && !flag) {
            //只修改了url
            wrapper.eq(FilterUrlConfigDO::getFilterType, old.getFilterType());
            wrapper.eq(FilterUrlConfigDO::getRequestUri, configBO.getRequestUri());
            count = filterUrlConfigMapper.count(wrapper);
        }
        if (count > 0) {
            throw new AppException("该地址已添加，请勿重复添加");
        }
        FilterUrlConfigDO configDO = FilterUrlConfigBeanUtil.filterUrlConfigBOToDO(configBO);
        filterUrlConfigMapper.updateById(configDO);

        init();

        return Boolean.TRUE;
    }

    @Override
    public Boolean deleteFilterUrl(Long[] ids) throws AppException {
        filterUrlConfigMapper.removeByIds(Arrays.asList(ids));
        init();
        return Boolean.TRUE;
    }

    @Override
    public FilterUrlConfigBO getFilterUrl(Long filterUrlConfigId) throws AppException {
        FilterUrlConfigDO configDO = filterUrlConfigMapper.getById(filterUrlConfigId);
        return FilterUrlConfigBeanUtil.filterUrlConfigDOToBO(configDO);
    }

    @Override
    public PageBO<FilterUrlConfigBO> findFilterUrlForPage(FilterUrlConfigQTO qto) throws AppException {
        PageBO<FilterUrlConfigBO> pageBO = new PageBO<>();
        if (qto == null) {
            return pageBO;
        }
        Integer count = filterUrlConfigMapper.findForPageCount(qto);
        if (count == null || count <= 0) {
            return pageBO;
        }
        List<FilterUrlConfigDO> doList = filterUrlConfigMapper.findForPage(qto);
        pageBO.setData(FilterUrlConfigBeanUtil.doList2BOList(doList), count);

        return pageBO;
    }

    @Override
    public Map<String, List<FilterUrlConfigBO>> findAllToMap() {
        List<FilterUrlConfigBO> boList = FilterUrlConfigBeanUtil.doList2BOList(filterUrlConfigMapper.findAll());
        if (CollectionUtils.isEmpty(boList)) {
            return new HashMap<>();
        }
        for (FilterUrlConfigBO bo : boList) {
            redisUtil.set(RedisKeyUtil.getFilterUrlKey(bo.getFilterType(), bo.getRequestUri()), bo.getRequestName());
        }
        Map<String, List<FilterUrlConfigBO>> result = boList.stream().collect(Collectors.groupingBy(FilterUrlConfigBO::getFilterType));

        return result;
    }
}
